﻿using System.Configuration;
using log4net.Config;
using Ninject;
using SelfMadeMillionaire.BLL.Services;
using SelfMadeMillionaire.Core;
using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Enums;
using SelfMadeMillionaire.Core.Services;
using SelfMadeMillionaire.DAL;
using SelfMadeMillionaire.Web.Infrastructure;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Security;

namespace SelfMadeMillionaire.Web
{
	// Note: For instructions on enabling IIS6 or IIS7 classic mode, 
	// visit http://go.microsoft.com/?LinkId=9394801

	public class MvcApplication : System.Web.HttpApplication
	{
        [Inject]
        public ILogService LogService { get; set; }
        [Inject]
        public ISubscriberService SubscriberService { get; set; }
        [Inject]
        public ILogVisitService LogVisitService { get; set; }

		protected void Application_Start()
		{
			XmlConfigurator.Configure();
			AreaRegistration.RegisterAllAreas();

			WebApiConfig.Register(GlobalConfiguration.Configuration);
			FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
			RouteConfig.RegisterRoutes(RouteTable.Routes);
			BundleConfig.RegisterBundles(BundleTable.Bundles);

			

			Database.SetInitializer(new MigrateDatabaseToLatestVersion<DataContext, SelfMadeMillionaire.DAL.Migrations.Configuration>());
		}

        protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
		{
			HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
			if (authCookie != null)
			{
				FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);

                // Check user
                /*var subscriber = SubscriberService.Get(ticket.Name);
                if (subscriber == null || subscriber.Status == (byte)StatusType.Deleted)
                {
                    FormsAuthentication.SignOut();
                }*/
                
				var roles = new List<string>();
				var userDataInfos = ticket.UserData.Split('|');

				foreach (var item in Enum.GetValues(typeof(UserRole)))
				{
					var userRole = UserRole.None;

					if (Enum.TryParse(userDataInfos[0], out userRole))
					{
						if (userRole == UserRole.None)
							roles.Add(UserRole.None.ToString());
						else
							if (((UserRole)Enum.Parse(typeof(UserRole), userDataInfos[0]) & (UserRole)item) == (UserRole)item)
								roles.Add(item.ToString());
					}
				}
                
				var principal = new CustomPrincipal(User.Identity, roles.ToArray());
				if(userDataInfos.Length > 1)
				{
					principal.FirstName = userDataInfos[1].Split(';')[0];
					principal.LastName = userDataInfos[1].Split(';')[1];

				}

				HttpContext.Current.User = principal;

			}
		}

        
        
        void Application_Error(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["IsDevelopmentEnvironment"])) return;

            Exception ex = Server.GetLastError();
            try
            {
                var user = HttpContext.Current.User;
               
                var log = new Log()
                {
                    DateAdded = DateTime.Now,
                    EventType = "Err",
                    EventMessage =
                        (ex.InnerException != null ? ex.InnerException.Message : ex.Message).Replace("'", "''"),
                    StackTrace =
                        (ex.InnerException != null ? ex.InnerException.StackTrace : ex.StackTrace).Replace("'", "''"),
                    CurrentUser = user != null ? user.Identity.Name : "",
                    Path = Context.Request.Path.Replace("'", "''"),
                    QueryString = Context.Request.QueryString.ToString(),
                    Browser = Context.Request.Browser.Browser,
                    UserHostAddress = Context.Request.UserHostAddress,
                    UrlReferrer = (Context.Request.UrlReferrer != null ? Context.Request.UrlReferrer.ToString() : "")
                };

                LogService.Add(log);
                
                Exception unhandledException = Server.GetLastError();
                new LoggingUtility().WriteErrorToLog(unhandledException);

                Server.ClearError();
            }
            catch (Exception exNew)
            {
                Response.Write("Unexpected error occurs (" + ex.Message + " -> " + exNew.Message + ")<br/>" + ex.StackTrace);
                Server.ClearError();
            }

        }

        void Session_Start(object sender, EventArgs e)
        {
            try
            {
                HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
                if (authCookie != null)
                {
                    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);

                    // Check user
                    var subscriber = SubscriberService.Get(ticket.Name);
                    if (subscriber == null || subscriber.Status == (byte)StatusType.Deleted)
                    {
                        FormsAuthentication.SignOut();
                        Response.Redirect("~");
                    }
                }

                var user = HttpContext.Current.User;
                var log = new LogVisit()
                {
                    DateAdded = DateTime.Now,
                    CurrentUser = user != null ? user.Identity.Name : "",
                    Path = Context.Request.Path.Replace("'", "''"),
                    QueryString = Context.Request.QueryString.ToString(),
                    Browser = Context.Request.Browser.Browser,
                    UserHostAddress = Context.Request.UserHostAddress,
                    UrlReferrer = (Context.Request.UrlReferrer != null ? Context.Request.UrlReferrer.ToString() : "")
                };
                LogVisitService.Add(log);
            }
            catch
            {
            }
        }
	}
}